package org.setaria.utils
{
	import flash.system.ApplicationDomain;
	import flash.utils.Dictionary;
	import flash.utils.getDefinitionByName;
	
	import mx.events.ModuleEvent;
	import mx.modules.IModuleInfo;
	import mx.modules.ModuleManager;
	
	import org.setaria.container.SetariaModule;
	import org.setaria.control.SetariaAlert;
	import org.setaria.cover.CoverManager;
	
	public class SetariaModuleManager
	{
		static private var modules:Dictionary = new Dictionary();
		static private var module:IModuleInfo; 
		/**
		 * 标志是否可以重复加载已经存在的module
		 * */
		static public var reload:Boolean = false;
		
		
		
		public function SetariaModuleManager()
		{
		}
		
		/**
		 * 按 类名 或 SWF路径 创建窗体
		 * @param link : 类路径或者swf路径
		 * @param onAddChild ： 回调函数,在窗体创建成功之后调度
		 **/
		static public function loadModule(link:String,onAddChild:Function,title:String = ""):void
		{
			var win:SetariaModule;
			var param:Object = resolvingParam(link);
			link = pureLink(link);
			if(modules[link]!=null && !reload){
				onAddChild(SetariaModule(modules[link]));
				return;
			}
			CoverManager.instance().cover(true);
			try{
				if(equalsSWF(link))
				{
					module = ModuleManager.getModule(link);
					module.addEventListener(ModuleEvent.PROGRESS,function(event:ModuleEvent):void{
						CoverManager.instance().loadInfo = draw(event.bytesLoaded,event.bytesTotal);
					});
					/**加载成功*/
					module.addEventListener(ModuleEvent.READY ,function(event:ModuleEvent):void
					{
						win = SetariaModule(event.module.factory.create()); 
						win.name = event.module.url;//创建module的实例
						win.data = param;//设置参数
						win.title = title;
						modules[win.name] = win;
						onAddChild(win);
						CoverManager.instance().cover(false);
					});
					/**加载失败*/
					module.addEventListener(ModuleEvent.ERROR ,function(event:ModuleEvent):void
					{
						event.module.unload();
						CoverManager.instance().cover(false);
						SetariaAlert.show("错误",event.errorText);
					});
					module.load(ApplicationDomain.currentDomain); //加载到内存中
				}
				else
				{
					var newClass:Class = getDefinitionByName(link) as Class;
					win = SetariaModule(new newClass());
					onAddChild(win);
				}
			}
			catch(error:Error)
			{
				trace(error.message);
			}
		}
		
		static public function unloadModule(link:String):void{
			delete(modules[link]);
			module = ModuleManager.getModule(link);
			if(module.loaded) 	//是否被加载到内存中
			{
				module.unload(); //卸载module
				module = null;
			}
		}
		
		static private function draw(completed:Number, total:Number):String  
		{   
			if (!isNaN(completed) && !isNaN(total) && completed >= 0 && total > 0)   
			{   
				var value:Number=Number(completed);   
				var maximum:Number=Number(total); 
				var currentLoad:Number=100*value/maximum;
				if (currentLoad > 99)   
					currentLoad = 99;   
				else  
					currentLoad = Math.round(currentLoad);  
				return "当前加载" +currentLoad  + "%";   
			} 
			return "当前加载 0%";
		} 
		
		/**
		 * 去掉url的参数，得到纯路径
		 **/
		static private function pureLink(link:String):String
		{
			var index:int = link.indexOf("?");
			if(index>0)
			{
				link = link.substring(0,index);
			}
			return link;
		}
		/**
		 * 解析路径中参数
		 **/
		static private function resolvingParam(link:String):Object
		{
			var param:Object;
			var paramStr:String = link.substring(link.indexOf("?")+1);
			if(paramStr!=null && paramStr.length>0)
			{
				var paras:Array = paramStr.split("&");
				param = new Object;
				for each(var p:String in paras){
					var index:int = p.indexOf("=");
					param[p.substring(0,index)] = p.substring(index+1);
				}
			}
			return param;
		}
		
		/**
		 * 否是SWF文件路径
		 **/
		static private function equalsSWF(link:String):Boolean
		{
			if(link && link.length > 3 && link.substr(link.length-1-3,4).toLowerCase() == ".swf")
			{
				return true;	
			}
			return false;
		}
		
		/**
		 * 得到obj中的属性,obj可以是xml或者Object
		 */
		static public function getProperty(obj:Object ,propertyName:String):*
		{
			var xmlproperty:String = "";
			if(obj is XML)
				xmlproperty = "@";
			return obj[xmlproperty+propertyName];
		}
	}
}